package com.allenkerr.lucene;

import org.apache.commons.io.FileUtils;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.LongField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * 针对 lucene 4 ，使用 IK-Analyzer 分词器
 * Created by 小柯(Allen Kerr) on 17.4.29 12:19.
 */
public class IndexManager4Lucene4 {
    //资源文件所在目录
    private static String searchSourceDirPath;
    //索引文件所在目录
    private static String searchIndexDirPath;

    //使用静态代码块加载配置文件，初始化属性
    static {
        InputStream inputStream = IndexManager4Lucene4.class.getClassLoader().getResourceAsStream("config.properties");
        Properties properties = new Properties();
        try {
            properties.load(inputStream);
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("读取配置文件失败！");
        }
        searchSourceDirPath = properties.getProperty("search_source_dir");
        searchIndexDirPath = properties.getProperty("search_index_dir");
    }

    /**
     * 索引创建，使用 IK-Analyzer 分词器
     */
    public static void createIndex() throws IOException {
        System.out.println("IndexManager4Lucene4.createIndex");
        //1. 创建文档列表，保存多个Document对象
        List<Document> docList = new ArrayList<>();

        //2. 指定资源文件所在的目录
        File sourceDir = new File(searchSourceDirPath);

        //3. 循环资源文件夹取出文件
        for (File file : sourceDir.listFiles()) {
            //文件名
            String fileName = file.getName();
            //文件内容
            String fileContext = FileUtils.readFileToString(file);
            //文件大小
            Long fileSize = FileUtils.sizeOf(file);

            //4. 使用TextField对象存值，构造函数(域名, 域值, 是否存储yes/no);
            //是否分词：yes，文件名需要提供搜索，且文件名可以分词
            //是否索引：yes，文件名需要索引，提供搜索
            //是否存储：yes，需要提供搜索结果的显示
            TextField nameField = new TextField("fileName", fileName, Field.Store.YES);
            // 是否分词：yes，文件内容需要提供搜索，且文件内容可以分词
            //是否索引：yes，文件内容需要索引，提供搜索
            //是否存储：yes or no，视搜索结果是否需要展示文件内容来定
            TextField contextField = new TextField("fileContext", fileContext, Field.Store.NO);
            // 是否分词：yes，文档大小需要使用lucene的算法进行分词，方便比较大小
            //是否索引：yes，文档大小也是搜索条件之一
            //是否存储：yes，需要在搜索结果里展示文档大小
            LongField sizeField = new LongField("fileSize", fileSize, Field.Store.YES);

            //5.1 创建文档对象(一个文件对应一个文档对象)
            Document doc = new Document();
            //5.2 将所有的域都存入文档对象中
            doc.add(nameField);
            doc.add(contextField);
            doc.add(sizeField);
            //5.3 将文档对象存储文档列表中
            docList.add(doc);
        }
        //6. 创建分词器，标准分词器StandardAnalyzer：支持英文，中文是单字分词
//        StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_4_10_3);
        IKAnalyzer analyzer = new IKAnalyzer();

        //7. 指定索引和文档存储的目录
        File indexDir = new File(searchIndexDirPath);
        Directory directory = FSDirectory.open(indexDir);

        //8. 创建写对象的初始化对象
        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_4_10_3, analyzer);

        //9. 创建索引和文档写对象
        IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);

        //10. 将文档加入到索引和文档的写对象中
        int i = 0;
        for (Document doc : docList) {
            indexWriter.addDocument(doc);
            i++;
        }
        System.out.println("共添加 " + i + " 条索引。");
        //11. 提交
        indexWriter.commit();
        //12. 关闭流
        indexWriter.close();
    }

    /**
     * 索引删除
     */
    public static void deleteIndex() throws IOException {
        //1. 创建分词器，StandardAnalyzer：良好支持英文，中文只能单字分词
//        StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_4_10_3);
        IKAnalyzer analyzer = new IKAnalyzer();
        //2. 指定索引和文档的目录
        File indexDir = new File(searchIndexDirPath);
        Directory directory = FSDirectory.open(indexDir);
        //3. 创建写对象的初始化对象
        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_4_10_3, analyzer);
        //4. 创建索引和文档写对象
        IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);

        //5. 删除索引
        //5.1 删除所有
        indexWriter.deleteAll();
        //5.2 根据名称删除
        //Term词元，就是一个词，构造函数(域名, 关键字);
//        indexWriter.deleteDocuments(new Term("fileName", "spring"));
//        indexWriter.deleteDocuments(new Term("fileContext", "spring"));
        //6. 提交
        indexWriter.commit();
        //7. 关闭
        indexWriter.close();
    }

}
